package jehc.cloud.job.client.handler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import jehc.cloud.common.base.BaseResult;
import jehc.cloud.common.util.JsonUtil;
import jehc.cloud.common.util.StringUtil;
import jehc.cloud.job.annotation.BaseJobAnnotation;
import jehc.cloud.job.client.NettyClient;
import jehc.cloud.job.client.NettyClientUtil;
import jehc.cloud.job.vo.ParamInfo;
import jehc.cloud.job.vo.RequestInfo;
import lombok.extern.slf4j.Slf4j;
import org.reflections.Reflections;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.Set;

/**
 * @Desc 客户端处理Handler
 * @Author 邓纯杰
 * @CreateTime 2012-12-12 12:12:12
 */
@Slf4j
@Component
public class NettyClientHandler extends ChannelInboundHandlerAdapter {
    private NettyClient nettyClient;

    private String clientId;//客户端id（每个服务对应一个客户端唯一id）

    private String clientGroupId;//组Id（可以存多个服务共享一个组Id）

    public NettyClientHandler(){

    }

    public NettyClientHandler(NettyClient nettyClient, String clientGroupId, String clientId){
        this.nettyClient = nettyClient;
        this.clientGroupId = clientGroupId;
        this.clientId = clientId;
    }


    /**
     * 连接服务器成功 发送握手信息
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        RequestInfo requestInfo = new RequestInfo();
        requestInfo.setClientGroupId(clientGroupId);
        requestInfo.setClientId(clientId);
        requestInfo.setShakeHands(true);
        requestInfo.setMessage("连接服务端成功");
        NettyClientUtil nettyClientUtil = new NettyClientUtil();
        nettyClientUtil.sendMessage(ctx.channel(),requestInfo);
        log.info("连接服务端成功 .....");
    }

    /**
     * 接收服务端信息
     * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        RequestInfo requestInfo = JsonUtil.fromAliFastJson(msg.toString(), RequestInfo.class);
        log.info("Received message from server: {}", requestInfo.getMessage());
        Reflections reflections = new Reflections("jehc");//扫描jehc包下所有类，包括引用的jar
        Set<Class<?>> typesAnnotatedWith = reflections.getTypesAnnotatedWith(BaseJobAnnotation.class);//获取带BaseJobAnnotation注解的类
        for (Class clazz : typesAnnotatedWith) {
            BaseJobAnnotation baseJobAnnotation = (BaseJobAnnotation)clazz.getAnnotation(BaseJobAnnotation.class);
            Method[] methods = clazz.getDeclaredMethods();
            for (Method method : methods) {
                /*不采用该方法
                //判断带自定义注解BaseJobAnnotation的method
                if (method.isAnnotationPresent(BaseJobAnnotation.class)) {
                    BaseJobAnnotation annotation = method.getAnnotation(BaseJobAnnotation.class);
                    if(annotation.jobKey().equals("execute")){
                        try {
                            method.invoke(clazz.newInstance());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
                */
                //或指定方法（默认）
                if(null != method &&
                        method.getName().equals("execute")&&
                        null != requestInfo &&
                        null != requestInfo.getJobHandlerEntity() &&
                        !StringUtil.isEmpty(requestInfo.getJobHandlerEntity().getJobName()) &&
                        !StringUtil.isEmpty(baseJobAnnotation.jobValue()) &&
                        requestInfo.getJobHandlerEntity().getJobName().equals(baseJobAnnotation.jobValue())){
                    try {
                        ParamInfo paramInfo = new ParamInfo();
                        paramInfo.setData(requestInfo.getObj());
                        BaseResult baseResult = (BaseResult)method.invoke(clazz.newInstance(),paramInfo);
                        log.debug("返回结果：{}",JsonUtil.toJson(baseResult));
                    } catch (Exception e) {
                        log.error("执行"+clazz.getName()+"类中execute方法异常...",e);
                    }
                }
            }
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }

    /**
     * 服务端挂了 调用重连机制
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        nettyClient.start();
        super.channelInactive(ctx);
    }

//    /**
//     * 客户端注册
//     * @param ctx
//     * @throws Exception
//     */
//    @Override
//    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
//        log.info("当前服务注册:" + ctx.channel().id());
//        /*
//        RequestInfo requestInfo = new RequestInfo();
//        requestInfo.setClientGroupId(clientGroupId);
//        requestInfo.setClientId(clientId);
//        requestInfo.setMessage("注册服务...");
//        Attribute attribute = ctx.channel().attr(JEHC_CLOUD_NETTY_CLIENT_CHANNEL);
//        attribute.set(requestInfo);
//        */
//        super.channelRegistered(ctx);
//    }
//
//    /**
//     * 客户端退出
//     * @param ctx
//     * @throws Exception
//     */
//    @Override
//    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
//        super.channelUnregistered(ctx);
//        /*
//        Object requestInfo = ctx.channel().attr(JEHC_CLOUD_NETTY_CLIENT_CHANNEL).get();
//        */
//        log.info("退出服务：" +ctx.channel().id().asLongText());
//    }
}
